'''
* This is the projet for Brtc LlmOps Platform
* @Author Leon-liao <liaosiliang@alltman.com>
* @Description //TODO 
* @File: 13_study_mult_input.py
* @Time: 2025/11/3
* @All Rights Reserve By Brtc
'''
import json
import os
from typing import Type, Any

import dotenv
import requests
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.tools import BaseTool
from langchain_openai import ChatOpenAI
from pydantic import BaseModel, Field

dotenv.load_dotenv()

class GaodeWeatherShema(BaseModel):
    city:str = Field(description="需要查询天气的城市,例如:武汉")

class GaodeWeatherTool(BaseTool):
    """根据传入的城市名称运行调用api 获取城市的天气预报信息"""
    name:str = "llmops_gaode_weather_tool"
    description:str = "当你查询天气的时候可以调用这个工具"
    args_schema:Type[BaseModel] = GaodeWeatherShema

    def _run(self, *args:Any, **kwargs:Any) -> Any:
        try:
            gaode_api_key = os.getenv("GAODE_API_KEY")
            gaode_api_url = os.getenv("GAODE_API_URL")
            if not gaode_api_key or not gaode_api_url:
                return f"请配置高德开放API_KEY 和 URL"
            else:
                #1、从参数中获取城市
                city = kwargs.get("city")
                #2、开始请求 高德服务获取 adcode
                session = requests.session()
                #3、行政code 请求
                city_response = session.request(
                    method="GET",
                    url = f"{gaode_api_url}/config/district?key={gaode_api_key}&keywords={city}&subdistrict=0",
                    headers={"Content-Type": "application/json; charset=utf-8"},
                )
                city_response.raise_for_status()
                city_data = city_response.json()
                if city_data.get("info") == "OK":
                    ad_code = city_data["districts"][0]["adcode"]
                    weather_info = session.request(
                        method="GET",
                        url=f"{gaode_api_url}/weather/weatherInfo?key={gaode_api_key}&city={ad_code}&extensions=all"
                    )
                    weather_info.raise_for_status()
                    weather_data = weather_info.json()
                    if weather_data.get("info") == "OK":
                        #返回天气的结果
                        return json.dumps(weather_data)
                    else:
                        return f"最后请求参数出错！！"
                else:
                    return f"请求城市编码出错！"
        except Exception as e:
            return f"开始获取天气的时候就出错了！{str(e)}"
# 1、构建 prompt
prompt = ChatPromptTemplate.from_messages([
    ("human",[
        {"type":"text", "text":"请获取下上传图片对应的城市的天气信息。"},
        {"type":"image_url", "image_url":{"url":"{image_url}"}}
    ])
])
weather_prompt = ChatPromptTemplate.from_template("""请整理下传递的城市天气预报信息, 并以用户友好的方式输出。
<weather>
{weather}
</weather>
""")
#2、构建LLM并绑定工具
llm = ChatOpenAI(model="gpt-4o-mini")
llm_with_tools = llm.bind_tools(tools=[GaodeWeatherTool()], tool_choice="llmops_gaode_weather_tool")

#3、创建链应用并执行
chain =(
    {
        "weather":(
            {"image_url":RunnablePassthrough()}
            |prompt
            |llm_with_tools
            |(lambda msg:msg.tool_calls[0]["args"])
            |GaodeWeatherTool()
        )
    }
    |weather_prompt|llm|StrOutputParser()
)
print(chain.invoke("https://img0.baidu.com/it/u=3678002511,4140441473&fm=253&app=138&f=JPEG?w=800&h=1773"))


